package com.yb.auth.core.filter;

import com.alibaba.fastjson2.JSONObject;
import com.yb.auth.core.bean.AbstractAuthentication;
import com.yb.auth.core.bean.SysUser;
import com.yb.auth.core.config.AuthIgnore;
import com.yb.core.bean.Resp;
import com.yb.core.constant.HttpConstant;
import com.yb.core.constant.RedisConstant;
import com.yb.core.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Copyright (C), 2022-2022, 姚兵
 * Author: 32210
 * Date: 2022/11/13 19:57
 * FileName: AuthTokenFilter
 * Description:
 */


@Component
@Slf4j
public class AuthTokenFilter extends OncePerRequestFilter {

    @Autowired
    RedisUtil redisUtil;


    @Autowired
    AuthIgnore authIgnore;

    AntPathMatcher antPathMatcher=new AntPathMatcher();
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("url:{}",request.getRequestURI());
        String token = request.getHeader(HttpConstant.AUTH_HEADER);
        response.setContentType("application/json;charset=utf-8");

        if(!StringUtils.hasText(token)){
            filterChain.doFilter(request,response);
            return;
        }

        boolean matched=false;

        for (String uri : authIgnore.getUrls()) {
            if(antPathMatcher.match(uri, request.getRequestURI())){
                matched=true;
                break;
            }
        }

        log.info("matched:{}",matched);
        if(matched){
            filterChain.doFilter(request,response);
            return;
        }
        String userStr = redisUtil.get(String.format(RedisConstant.AUTH_TOKEN_KEY, token));
        if(!StringUtils.hasText(userStr)){
            response.getWriter().write(JSONObject.toJSONString(Resp.ok(HttpConstant.Response.TOKEN_ERROR)));
//            filterChain.doFilter(request,response);
            return;
        }

        SysUser sysUser = JSONObject.parseObject(userStr, SysUser.class);

        log.info("sysUser:{}",JSONObject.toJSONString(sysUser));




        Authentication authenticated = AbstractAuthentication.authenticated(sysUser, sysUser.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authenticated);
        filterChain.doFilter(request,response); //放行

    }
}
